A Model Context Protocol (MCP) server that gives AI coding agents real,
live, source-cited documentation for npm and PyPI packages — pulled
directly from registry.npmjs.org and pypi.org at call time.
Built by ScriptMaster Labs.
Every tool call makes a real HTTP request to the actual registry. There is
no cached demo data, no fabricated example output, and no guessing. If a
package or its docs can't be found, the tool returns an explicit error —
never a plausible-looking made-up answer. Every successful response
includes source_url and fetched_at so the caller can verify exactly
where the data came from and how fresh it is.
Not yet built (honest status, not hype):
- Payment/licensing (Stripe, API keys, usage tiers) — this is scaffolding work that needs your real Stripe account and pricing decisions. Nothing in this repo simulates a working payment system.
- GitHub-source doc fetching beyond README/long-description (e.g. specific guide pages, versioned doc sites) — README/long-description only in v0.1.
| Tool | What it does |
|---|---|
docs_get_package_info |
Live metadata: latest version, description, homepage, repo — npm, PyPI, or Cargo (crates.io), right now. |
docs_get_readme |
The verbatim README (npm), long description (PyPI), or README-derived text (Cargo — see note below) for a package/version. |
docs_search_docs |
Keyword search inside a package's real docs (any of the 3 ecosystems, optionally a specific version), returns verbatim matching snippets with context — not a summary. |
docs_check_vulnerabilities |
Checks a specific package+version against OSV.dev. When a fix exists, automatically fetches that fixed version's README in the same call — "here's what's wrong" and "here's what upgrading looks like," one round trip. |
docs_resolve_library |
Fuzzy name → real candidates, via npm's and crates.io's actual search APIs. PyPI has no official search API (confirmed: XML-RPC search was killed in 2022, never replaced) — calling this for PyPI returns an honest explanation, not a scraped or fabricated result. |
Note on Cargo READMEs: crates.io stores READMEs pre-rendered as HTML, not the original markdown source — there's no raw-source endpoint. docs_get_readme/docs_search_docs return that HTML converted to plain text (tags stripped, entities decoded) — a mechanical transformation, not a summary; no content is invented or dropped.
scriptdocs-mcp-server/
├── package.json
├── tsconfig.json
├── Dockerfile
├── src/
│ ├── index.ts # server entry point, transport selection
│ ├── constants.ts
│ ├── types.ts
│ ├── services/
│ │ ├── npm.ts # real npm registry client
│ │ ├── npmSearch.ts # real npm search API (fuzzy resolution)
│ │ ├── pypi.ts # real PyPI registry client (supports version pinning)
│ │ ├── cargo.ts # real crates.io client (metadata, readme, search)
│ │ ├── osv.ts # real OSV.dev vulnerability database client
│ │ ├── versionCompare.ts # best-effort numeric version comparator
│ │ ├── access.ts # founder always-free guarantee
│ │ └── docSearch.ts # keyword/snippet extraction over fetched text
│ └── tools/
│ ├── getPackageInfo.ts
│ ├── getReadme.ts
│ ├── searchDocs.ts
│ ├── checkVulnerabilities.ts
│ └── resolveLibrary.ts
└── dist/ # build output (git-ignored)
npm install
npm run build
node dist/index.jsTo wire it into Claude Desktop or Cursor, point their MCP config at:
{
"mcpServers": {
"scriptdocs": {
"command": "node",
"args": ["/absolute/path/to/scriptdocs-mcp-server/dist/index.js"]
}
}
}npm install
npm run build
TRANSPORT=http PORT=3000 node dist/index.js- Health check:
GET /health - MCP endpoint:
POST /mcp
The included Dockerfile builds and runs the HTTP transport. Point a
Render Web Service at this repo with:
- Environment: Docker
- Health check path:
/health
This mirrors how mcp-x402 and squeezeos-api are already deployed.
-
v0.3.1 fixed a real published-package bug:
dist/index.jshad no#!/usr/bin/env nodeshebang and wasn't marked executable, so running it as a bin (exactly whatnpx/Claude Code do) failed — on Linux with a shell syntax error, and this was very likely the cause of the "Failed to connect" a real Windows user hit via Claude Code. Root cause confirmed by directly executing the packed tarball's bin file before and after the fix, not assumed.postbuildnow runschmod +x dist/index.jsso this can't silently regress. -
docs_get_package_info→express(npm),serde(cargo) returned real current metadata straight from their respective registries. -
docs_get_readme→zod(npm, jsDelivr fallback),requests(PyPI, latest + version-pinned), andserde(cargo) all returned real README content. The cargo path hit a real bug during testing — crates.io's README endpoint varies its response byAcceptheader and was returning a JSON pointer instead of HTML — caught and fixed, verified again after the fix. -
docs_search_docs→ keyword search over real docs verified across npm and cargo. -
docs_check_vulnerabilities→express@4.17.1correctly returned 2 real advisories (incl. CVE-2024-43796) and automatically fetched the real README for4.20.0(the fixed version) in the same call — the vuln-to-fix bridge, verified working end-to-end. -
docs_resolve_library→ real fuzzy search verified for npm ("react" → react, react-is, ...) and cargo ("http client" → real candidates). PyPI correctly returns an honest limitation message instead of a fabricated result (verified: PyPI has had no official search API since 2022). -
Nonexistent package name → correctly returns an explicit
isError: trueresponse instead of fabricating a plausible answer. -
Both
stdioandTRANSPORT=httpmodes verified against the actual MCP JSON-RPC protocol (initialize,tools/list,tools/call).
ScriptMaster Labs (you) always gets full, unmetered, free access to every tool this server exposes — no matter what paid tiers get built later. This is baked into the architecture now, before any billing exists, not retrofitted after the fact:
src/services/access.tsexportsisOwnerRequest(), checked against a secret in theSCRIPTDOCS_OWNER_KEYenvironment variable (never hardcoded — this repo is public, so a hardcoded bypass would give everyone free access, not just you).- The HTTP transport already tags every request with an
x-scriptdocs-access-tierresponse header (owner-unlimitedorstandard) — verified working, not just written. - Rule for any future billing/rate-limit code: call
isOwnerRequest()first and skip all limits/charges when it returns true.
To use it once deployed: set SCRIPTDOCS_OWNER_KEY as an environment
variable on your Render service, then send requests with header
x-scriptdocs-owner-key: <that value>. Keep the value secret — it's
not in this repo, and shouldn't be.
There's no "beat Context7's ranking" button. There's one source-of-truth
feed and a handful of directories that read from it. This is the real,
current (as of July 2026) process, verified against the official docs at
modelcontextprotocol.io/registry:
- The official MCP Registry (
registry.modelcontextprotocol.io) is what a growing number of AI clients read to discover servers. There's no review queue — you publish aserver.jsonrecord under a namespace you prove you own, and it's live. - Discovery directories — Smithery, Glama, PulseMCP, mcp.so — crawl GitHub and the registry on their own. You may already show up there unclaimed once this is public; claiming ownership is what lets you control the description instead of a bot's guess.
package.jsonhas"mcpName": "io.github.Timwal78/scriptdocs-mcp-server"and is renamed to the scoped package@scriptmasterlabs/scriptdocs-mcp-server(under the existing@scriptmasterlabsorg scope — same one publishingmcp-x402andmcp-x402-sdk— rather than a personal scope, since this sits alongside your other MCP infrastructure)server.jsonis written and validated against the real, live official schema (static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json) — not guessed at..github/workflows/publish-mcp.ymlauto-publishes to npm and the MCP Registry every time you push av*tag, using the official OIDC flow (no registry secret needed — just anNPM_TOKEN).- License changed from
UNLICENSEDtoMIT— a package meant for strangers to install needs a license that actually lets them use it.
- Push this to a public GitHub repo at
github.com/Timwal78/scriptdocs-mcp-server(or wherever you want it — updaterepositoryinpackage.jsonandserver.jsonto match if the path differs). - Add an
NPM_TOKENsecret to that repo (Settings → Secrets → Actions) from an npm access token tied to your npm account. - Tag and push a release:
git tag v0.2.0 && git push origin v0.2.0— the workflow handles npm publish + MCP Registry publish automatically from there. - Claim your listing on Smithery, Glama, and PulseMCP once the registry record is live — they crawl and often list you automatically, but claiming moves you from "anonymous crawl result" to a verified, owner-controlled listing.
Context7 has real scale (tens of thousands of installs, broad ecosystem coverage) built over time. What actually makes a server "a viable alternative" in these registries isn't a claim in a README — it's real uptime, a working install, and accurate tool descriptions, which is what steps 1-4 above get you: correctly listed, discoverable, and functioning. Nothing here fabricates traction that doesn't exist yet.
- Licensing/monetization — needs your real Stripe/x402 decisions and pricing before anything gets built here. Research so far: Context7 (the main comparable) keeps public docs lookup free indefinitely and monetizes private-library support + team seats + compliance, not public lookups. Freemium dev-tools convert free→paid at 2-4% typically (8-12% is considered great).
- Private/internal library support — the one proven lever in this category (see above) — needs a hosted service (see #6 below), not yet built.
- PyPI fuzzy resolution — not buildable against PyPI's official API (confirmed: no search API has existed since 2022). Only real option is leaning on an unofficial third-party index/mirror, with the tradeoffs that implies.
- Go modules — metadata support (versions, checksums) would follow
the same pattern as npm/PyPI/Cargo. Fuzzy resolution would not:
confirmed
proxy.golang.orghas no search endpoint at all. - Real relevance ranking (semantic search, not keyword substring) — buildable, but the real version needs an embeddings API (real ongoing cost) and a vector store — a spend decision, not built yet.
- Remote (HTTP) registry listing + hosted deployment — needed as
the foundation for private-library support and any future rate
limiting;
server.jsonsupports adding aremotesentry once this is deployed to Render with a public URL. - Caching layer — currently every call hits the live registry fresh (correct for accuracy, but means repeated calls for the same package in one session re-fetch). A short in-memory TTL cache would cut latency without sacrificing truthfulness — not yet built.